#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,a,b) for(register int i = (a);i <= (b);++i)
#define per(i,a,b) for(register int i = (a);i >= (b);--i) 
#define mkp std::make_pair
typedef long long ll;
typedef unsigned long long ull;
using std::string;using std::cin;using std::cout;
inline bool cmp(int x,int y){return x < y;}

const int N = 1e6+9;
const int inf = 1e9+9;
const double eps = 1e-7;
int _,n,m,u,v,w,map[2200][2200],cnt[2200];
bool vis[2200];
std::priority_queue< std::pair<int,int> >q;

int head[2*N],ver[2*N],next[2*N],edge[2*N],tot,dis[2*N];
inline void link(int x,int y,int z){ver[++tot] = y , edge[tot] = z , next[tot] = head[x] , head[x] = tot;}

inline void dij(){
    while(q.size()) q.pop();
    rep(i,1,n) dis[i] = inf;
    cnt[1] = 1 , dis[1] = 0;
    q.push(mkp(-inf*2,1));
    while(q.size()){
        int to,now  = q.top().second;  q.pop();
        if(vis[now]) continue;
        vis[now] = true;
        for(int i = head[now];i;i = next[i]){
            to = ver[i];
            if(dis[to] == dis[now] + edge[i]) cnt[to] += cnt[now];
            else if(dis[to] > dis[now] + edge[i]){
                dis[to] = dis[now] + edge[i] , cnt[to] = cnt[now];
                q.push(mkp(-dis[to],to));
            }
        }
    }    
}

int main(){
    std::ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    #ifdef LOCAL //use "g++ xxx.cpp -DLOCAL"
        freopen("in.in", "r", stdin);
    #endif
    cin >> n >> m;
    rep(i,1,n) rep(j,1,n) map[i][j] = inf;
    rep(i,1,m){
        cin >> u >> v >> w;
        if(map[u][v] == 0 || map[u][v] > w){link(u,v,w);map[u][v] = w;}
    }
    dij();

    if(dis[n] == inf) cout << "No answer\n";
    else cout << dis[n] << " " << cnt[n] << "\n";
    return 0;
}